﻿'**************************************************************
'CATECO_UDF_001.0  catia / ecotect interoperability
'ben howes, matt naugle, alex gonzales - 05.09.11
'
'This work is licensed under the GNU Generic Public License v3.
'See http://www.gnu.org/licenses/gpl.html For more license information.
'
'
'Creates a link between catia And ecotect Using catia's exposed COM objects 
'And ecotect's dde server.  Props to the proving ground (and uto) for the dde trick.
'
'
'**************************************************************

''IMPORT NAMESPACES
''****************************************************
								''make sure to add these COM libraries
Imports GenKwe  				''CATIA V5 GenKnowledgeInterfaces
Imports INFITF  				''CATIA V5 InfInterfaces
Imports HybridShapeTypeLib		''CATIA V5 GSMInterfaces
Imports KnowledgewareTypeLib	''CATIA V5 KnowledgeInterfaces
Imports PARTITF					''CATIA V5 PartInterfaces
Imports MECMOD					''CATIA V5 MecModInterfaces
Imports SPATypeLib				''CATIA V5 SpaceAnalysisInterfaces


Module CatecoUdfMain
	
''**GLOBAL VARIABLES
''****************************************************

	Dim myForm As MainForm

	Dim myPart As Part
	Dim eco As Cateco
	Dim myPoints(,) As HybridShapePointOnCurve
	Dim curveNumber As Integer
	Dim surfNumber As Integer
	Dim myCatecoGeoSet As HybridBody
	Dim myOrderedGeoSets As OrderedGeometricalSets
	Dim myOrderedSetsList() As String
	Dim myPartParameters As Parameters
	Dim myParameterList() As String
	
	
''**PUBLIC PROPERTIES
''****************************************************	
	ReadOnly Property readOrderedSetsList As String() 
		Get
			Return myOrderedSetsList
		End Get
	End Property
	
	ReadOnly Property readParameterList As String()
		Get
			Return myParameterList
		End Get
	End Property	
	
''**MAIN SCRIPT FUNCTION
''****************************************************
	Public Sub myMain()
		
		myForm = My.Forms.MainForm
		
		''initCatia
		initEcotect
		arraySize
		newGeoSet
		udfCrvPts
		ecotect
		insolationResults
		
		''colorTest
		
		msgBox("done!")
	End Sub
	
''**PUBLIC SUBROUTINES
''*****************************************************

''**Initialize catia and publish part to use in the other subs
	Public Sub initCatia()
		Dim myCatia As Application = GetObject(, "Catia.Application")
		Dim myDoc As PartDocument = myCatia.ActiveDocument
		myPart = myDoc.Part
		getCatiaSetsAndParams
	End Sub
	
''**Get ordered Geo sets and parameters out of part for use in form dropdowns	
	Public Sub getCatiaSetsAndParams()
		myOrderedGeoSets = myPart.OrderedGeometricalSets
		
		Dim myOrderedGeoSet As OrderedGeometricalSet
		ReDim myOrderedSetsList (0 To myOrderedGeoSets.Count)
		
		For i=0 To myOrderedGeoSets.Count-1
			
			myOrderedGeoSet = myOrderedGeoSets.Item(i+1)
			myOrderedSetsList(i) = myOrderedGeoSet.Name
			''MsgBox(myOrderedSetsList(i))
			
		Next i
		
		
		myPartParameters = myPart.Parameters
		Dim myRootParamSet As ParameterSet = myPartParameters.RootParameterSet
		
		Dim myRootParameters As Parameters = myRootParamSet.AllParameters
	
		Dim myParameter As Parameter
		ReDim myParameterList (0 To myRootParameters.Count)
		
		For j=0 To myRootParameters.Count-1
			
			myParameter = myRootParameters.Item(j+1)
			myParameterList(j) = myParameter.Name
			''MsgBox( myParameterList(j) )
			
		Next j
		
	End Sub
		
''**Initialize ecotect and publish eco object for use in other subs
	Public Sub initEcotect()
		eco = New Cateco()
	End Sub
	
''**Read and publish driving parameters; redimension points array
	Public Sub arraySize()
		
		curveNumber = Int(myPart.Parameters.Item(myForm.readMyUParam).ValueAsString)
    	surfNumber = Int(myPart.Parameters.Item(myForm.readMyVParam).ValueAsString)
    	
    	ReDim myPoints(0 To curveNumber, 0 To surfNumber)
    	
	End Sub
	
''**New gemoetrical Set
	Public Sub newGeoSet()
		
		Dim myHybridBodies As HybridBodies = myPart.HybridBodies
		myCatecoGeoSet = myHybridBodies.Add()
		
    	myCatecoGeoSet.Name = "CATECO"
    	
    	myPart.Update
    	
	End Sub
	
''**Points on UDF curves
	Public Sub udfCrvPts()
	
	''**get the ordered geo set
    Dim myOrderedGeoSet As OrderedGeometricalSet = myPart.OrderedGeometricalSets.Item(myForm.readMyCurvesSet)
    
    ''**get the collection of curves in 'CURVES'
    Dim myCrvs As HybridShapes = myOrderedGeoSet.HybridShapes
    
    ''**create a hybrid shape factory
    Dim myFactory As HybridShapeFactory = myPart.HybridShapeFactory
    
    ''**nested for loop to populate myPoints array
    For i=0 To curveNumber-1
    	For j=0 To surfNumber
    		
    		''**create points (of type pointOnCurve) on the curves in the curves collection in the CATECO geo set
            Dim myPointOnCurve As HybridShapePointOnCurve = myFactory.AddNewPointOnCurveFromPercent(myCrvs.Item(i+1), j / surfNumber, False)
    		
    		''**append to geo set and add to myPoints array
            myCatecoGeoSet.AppendHybridShape(myPointOnCurve)
            myPoints(i, j) = myPointOnCurve
    	Next j
    Next i
    
    myPart.Update
    
    
    
		
	End Sub
	
''**Ecotect
	Public Sub ecotect()
		''**initialize
		eco.connect()
		eco.activate()
		eco.newModel()
		
		''**load shading file if there is one and load the weather file
		eco.shadingFile = myForm.readMyShadingFileLocation
		If myForm.readMyShadingFileLocation <> ""
			eco.loadShadingFile()
		End If 
	
		eco.weatherFile = myForm.readMyWeatherFileLocation
		eco.loadWeatherFile()
		
		eco.update()
		
		''**set object counter = to number of shading objects in the model
		Dim objectCounter As Integer = eco.numShadingObjects
		
		eco.addZone()
		
		''**create objects
		
'		''**loop through to create QUAD FACEs
'		For i=0 To curveNumber-2
'			For j=0 To 	Number-1
'
'				eco.createWallObject()
'
'				dim nodeCounter as Integer = 0
'				Dim fakePoint = myPoints(i,j)
'				Dim myPointCoords(2) as Object
'				fakePoint.GetCoordinates(myPointCoords)
'				eco.addNodeToObject(objectCounter,nodeCounter,myPointCoords(0),myPointCoords(1),myPointCoords(2))
'				nodeCounter = nodeCounter + 1
'
'				fakePoint = myPoints(i+1,j)
'				fakePoint.GetCoordinates(myPointCoords)
'				eco.addNodeToObject(objectCounter,nodeCounter,myPointCoords(0),myPointCoords(1),myPointCoords(2))
'				nodeCounter = nodeCounter + 1
'
'				fakePoint = myPoints(i+1,j+1)
'				fakePoint.GetCoordinates(myPointCoords)
'				eco.addNodeToObject(objectCounter,nodeCounter,myPointCoords(0),myPointCoords(1),myPointCoords(2))
'				nodeCounter = nodeCounter + 1
'
'				fakePoint = myPoints(i,j+1)
'				fakePoint.GetCoordinates(myPointCoords)
'				eco.addNodeToObject(objectCounter,nodeCounter,myPointCoords(0),myPointCoords(1),myPointCoords(2))
'				nodeCounter = nodeCounter + 1
'
'				eco.objectDone()
'				objectCounter = objectCounter+1
'			Next j
'		Next i
'		eco.update()
		
		''**loop through to create TRIANGLE FACEs
		For i=0 To curveNumber-2
			For j=0 To surfNumber-1
				
				Dim nodeCounter As Integer = 0
				Dim myPointCoords(2) As Object
				
				eco.createWallObject()
				
					Dim fakePoint = myPoints(i,j)
					fakePoint.GetCoordinates(myPointCoords)
					eco.addNodeToObject(objectCounter,nodeCounter,myPointCoords(0),myPointCoords(1),myPointCoords(2))
					nodeCounter = nodeCounter + 1
					
					fakePoint = myPoints(i+1,j)
					fakePoint.GetCoordinates(myPointCoords)
					eco.addNodeToObject(objectCounter,nodeCounter,myPointCoords(0),myPointCoords(1),myPointCoords(2))
					nodeCounter = nodeCounter + 1
	
					fakePoint = myPoints(i+1,j+1)
					fakePoint.GetCoordinates(myPointCoords)
					eco.addNodeToObject(objectCounter,nodeCounter,myPointCoords(0),myPointCoords(1),myPointCoords(2))
					nodeCounter = nodeCounter + 1
				
				eco.objectDone()
				objectCounter = objectCounter+1
				
				
				eco.createWallObject()
				nodeCounter = 0
				
					fakePoint = myPoints(i+1,j+1)
					fakePoint.GetCoordinates(myPointCoords)
					eco.addNodeToObject(objectCounter,nodeCounter,myPointCoords(0),myPointCoords(1),myPointCoords(2))
					nodeCounter = nodeCounter + 1
					
					fakePoint = myPoints(i,j+1)
					fakePoint.GetCoordinates(myPointCoords)
					eco.addNodeToObject(objectCounter,nodeCounter,myPointCoords(0),myPointCoords(1),myPointCoords(2))
					nodeCounter = nodeCounter + 1
	
					fakePoint = myPoints(i,j)
					fakePoint.GetCoordinates(myPointCoords)
					eco.addNodeToObject(objectCounter,nodeCounter,myPointCoords(0),myPointCoords(1),myPointCoords(2))
					nodeCounter = nodeCounter + 1
				
				eco.objectDone()
				objectCounter = objectCounter+1

			Next j
		Next i
		eco.update()
		eco.fitGrid()
		eco.update()
		
		''**insolation
		eco.setCalcDates(myForm.readMyStartDate,myForm.readMyEndDate)
		eco.setCalcPrecision(3)    ''**0 is most accurate, 4 is least
		eco.setClacTimes(myForm.readMyStartTime, myForm.readMyEndTime,1)
		eco.update()
		''**errorchecking next two lines*****************************
'		eco.getCalcDates
'		MsgBox(eco.calcDates)
		eco.calcInsolation(myForm.readMyInsolationInt, myForm.readMyCalcObjectInt, myForm.readMyAccumulationInt)

		
		eco.update()
		
		''**set up the catia sellection object
		Dim myCatia As Application = GetObject(, "Catia.Application")
		Dim mySel as Selection
		mySel = myCatia.ActiveDocument.Selection
		mySel.Clear
		
		mySel.Add(myCatecoGeoSet)
		mySel.Delete
		
		myPart.Update
		eco.disconnect()
	End Sub
	
	''**write the insolation values to the udfs, and change their color
	Public Sub insolationResults()
		
		''**set up the catia sellection object
		Dim myCatia As Application = GetObject(, "Catia.Application")
		Dim mySel as Selection
		mySel = myCatia.ActiveDocument.Selection
		mySel.Clear
		
		''**get the ordered geo set
    	Dim myOrderedGeoSet As OrderedGeometricalSet = myPart.OrderedGeometricalSets.Item(myForm.readMySurfSet)
    	''**get the collection of curves in 'CURVES'
    	Dim mySrfs As HybridShapes = myOrderedGeoSet.HybridShapes
		
		''**connect to ecotect
		eco.connect()
		''**get attribute scale min and max, create mid point
		eco.getAttributeScale()
		Dim myMaxVal As Double = eco.scaleMax
		Dim myMinVal As Double = eco.scaleMin
		Dim myMidVal As Double = (myMaxVal+myMinVal)/2
		Dim myValStepSize As Double = (eco.scaleMax - eco.scaleMin)/11
		
		''**loop over the objects in the arraylist, write insolation value to udf, update udf color
		For i=0 To ((curveNumber-1)*surfNumber)-1
			
			''**local variables for the triangle faces' inslovation values; average
			Dim face1,face2,faceAvg As Double
			
			''**request the insolation values for each i
			If eco.numShadingObjects = 0 Then
				eco.requestInsolationValue(1,i*2) 
				eco.requestInsolationValue(1,(i*2)+1)
			Else
				eco.requestInsolationValue(1,((i+eco.numShadingObjects)*2)-eco.numShadingObjects) ''add the # of shading objects herre
				eco.requestInsolationValue(1,((i+eco.numShadingObjects)*2)-eco.numShadingObjects+1)  ''same here
			End If
			
				
			''**get the attributes from the list
			face1 = eco.attributeList(i*2)
			face2 = eco.attributeList((i*2)+1)
			faceAvg = (face1 + face2)/2  ''average
			
			''**write the average value to the "myInsolationValue" parameter in the surf UDFs
			myPart.Parameters.Item("roofdesign\SURF\panel."& i+1 &"\myInsolationValue").value = faceAvg
'			Dim myStringName As String = myForm.readMyInsolationName
'			MsgBox(myStringName)
'			Dim myFullStringName As String = "roofdesign\SURF\panel." & i+1 & myStringName
'			MsgBox(myFullStringName)
'			myPart.Parameters.Item(myFullStringName).value = faceAvg
'			''myPart.Parameters.Item("roofdesign\SURF\panel."& i+1 & myStringName).value = faceAvg
			
			''**add the (i)th face to the selection
			mySel.Add(mySrfs.Item(i+1))
			
'			''**the color bit that needs finishing up - this doesnt work... 


			If faceAvg <= myMaxVal And faceAvg > (myMaxVal - myValStepSize) Then
				mySel.VisProperties.SetRealColor(255,255,0,1)
			End If
			
			If faceAvg <= (myMaxVal - myValStepSize) And faceAvg > (myMaxVal - (myValStepSize*2)) Then
				mySel.VisProperties.SetRealColor(255,226,0,1)
			End If
			
			If faceAvg <= (myMaxVal - (myValStepSize*2)) And faceAvg > (myMaxVal - (myValStepSize*3)) Then
				mySel.VisProperties.SetRealColor(255,173,0,1)
			End If
			
			If faceAvg <= (myMaxVal - (myValStepSize*3)) And faceAvg > (myMaxVal - (myValStepSize*4)) Then
				mySel.VisProperties.SetRealColor(255,119,0,1)
			End If
			
			If faceAvg <= (myMaxVal - (myValStepSize*4)) And faceAvg > (myMaxVal - (myValStepSize*5)) Then
				mySel.VisProperties.SetRealColor(255,66,0,1)
			End If
			
			If faceAvg <= (myMaxVal - (myValStepSize*5)) And faceAvg > (myMaxVal - (myValStepSize*6)) Then
				mySel.VisProperties.SetRealColor(255,12,0,1)
			End If
			
			If faceAvg <= (myMaxVal - (myValStepSize*6)) And faceAvg > (myMaxVal - (myValStepSize*7)) Then
				mySel.VisProperties.SetRealColor(214,0,41,1)
			End If
			
			If faceAvg <= (myMaxVal - (myValStepSize*7)) And faceAvg > (myMaxVal - (myValStepSize*8)) Then
				mySel.VisProperties.SetRealColor(160,0,95,1)
			End If
			
			If faceAvg <= (myMaxVal - (myValStepSize*8)) And faceAvg > (myMaxVal - (myValStepSize*9)) Then
				mySel.VisProperties.SetRealColor(160,0,95,1)
			End If
			
			If faceAvg <= (myMaxVal - (myValStepSize*9)) And faceAvg > (myMaxVal - (myValStepSize*10)) Then
				mySel.VisProperties.SetRealColor(107,0,148,1)
			End If
			
			If faceAvg <= (myMaxVal - (myValStepSize*10)) And faceAvg > (myMaxVal - (myValStepSize*11)) Then
				mySel.VisProperties.SetRealColor(53,0,202,1)
			End If
			
			If faceAvg <= (myMaxVal - (myValStepSize*11)) And faceAvg > myMinVal Then
				mySel.VisProperties.SetRealColor(0,0,255,1)
			End If
			
			''**clear the selection
			mySel.Clear
		Next i
		
		''**disconnect from ecotect
		eco.disconnect()
	End Sub
	
''**Change the color of an object
	Public Sub colorTest()
		
		Dim myCatia As Application = GetObject(, "Catia.Application")
		Dim mySel as Selection
		mySel = myCatia.ActiveDocument.Selection
		mySel.Clear
		
		''**get the ordered geo set
    	Dim myOrderedGeoSet As OrderedGeometricalSet = myPart.OrderedGeometricalSets.Item(myForm.readMySurfSet)
    
    	''**get the collection of curves in 'CURVES'
    	Dim mySrfs As HybridShapes = myOrderedGeoSet.HybridShapes
    	
    	mySel.Add(mySrfs.Item(1))
    	mySel.VisProperties.SetRealColor(255,0,0,0)
    	myPart.Update


	End Sub
	
	
End Module
